#include "LeakyReLUBPNetwork.hpp"
#include <iostream>

int main() {
    try {
        // 1. 创建LeakyReLU BP网络（2输入+3隐藏+1输出，学习率0.01）
        LeakyReLUBPNetwork net({2, 3, 1}, 0.01);
        // （可选）调整隐藏层神经元的负斜率为0.05
        net.setNeuronSlope(0, 0, 0.05);
        net.setNeuronSlope(0, 1, 0.05);
        net.setNeuronSlope(0, 2, 0.05);

        // 2. 异或训练数据
        std::vector<std::pair<std::vector<double>, std::vector<double>>> trainingData = {
            {{0, 0}, {0}},
            {{0, 1}, {1}},
            {{1, 0}, {1}},
            {{1, 1}, {0}}
        };

        // 3. 训练10000轮（每2000轮衰减学习率）
        for (int epoch = 0; epoch < 10000; ++epoch) {
            for (const auto& data : trainingData) {
                net.train(data.first, data.second);
            }
            // 每2000轮衰减学习率（衰减率0.9）
            if (epoch % 2000 == 0 && epoch != 0) {
                net.setLearningRate(net.getLearningRate() * 0.9);
            }
            // 每1000轮打印进度
            if (epoch % 1000 == 0) {
                std::cout << "Epoch " << epoch << " 完成 | 当前学习率: " << net.getLearningRate() << std::endl;
            }
        }

        // 4. 测试网络（LeakyReLU稳定性显著优于普通ReLU）
        std::cout << "\nLeakyReLU BP网络测试结果：" << std::endl;
        for (const auto& data : trainingData) {
            std::vector<double> output = net.get(data.first);
            std::cout << "输入: (" << data.first[0] << "," << data.first[1] 
                      << ") | 输出: " << output[0] 
                      << " | 期望: " << data.second[0] << std::endl;
        }

        // 5. 保存与加载模型
        net.store("leaky_xor_model.bin");
        std::cout << "\n模型已保存至 leaky_xor_model.bin" << std::endl;

        LeakyReLUBPNetwork netLoaded({2, 3, 1});  // 需与原网络结构一致
        netLoaded.load("leaky_xor_model.bin");
        std::cout << "\n加载模型后测试：" << std::endl;
        for (const auto& data : trainingData) {
            std::vector<double> output = netLoaded.get(data.first);
            std::cout << "输入: (" << data.first[0] << "," << data.first[1] 
                      << ") | 输出: " << output[0] << std::endl;
        }

    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}